package data.nanjing.expo.ctrls;

import data.nanjing.expo.common.Result;
import data.nanjing.expo.common.VerifyCodeExportUtil;
import data.nanjing.expo.models.domain.FileManage;
import data.nanjing.expo.models.domain.User;
import data.nanjing.expo.models.domain.dto.exhibition.*;
import data.nanjing.expo.models.domain.exhibition.Exhibition;
import data.nanjing.expo.models.domain.exhibition.ModifyStandInfoDto;
import data.nanjing.expo.models.domain.exhibition.ParticipantListDto;
import data.nanjing.expo.models.domain.exhibition.Participants;
import data.nanjing.expo.services.ExpoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.util.*;

/**
 * @author ChanJi
 */
@Controller
@RestController
@RequestMapping("/api/expo")
public class ExpoCtrl extends BaseCtrl {
    @Autowired
    private ExpoService exhibitionService;

    /**
     * 上传展会基本信息
     * @param expo
     * @return
     */
    @PostMapping("/create/baseInfo")
    public Result uploadBaseInfo(@Valid UploadExpoDto expo, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        User user = this.getUserFromSession(request);
        Integer userId = user.getId();
        expo.setUserId(userId);
        Integer expoId = exhibitionService.getExpoIdByName(expo.getExpoName());
        if (expoId != null) {
            return this.send(1001, "展会名称重复");
        }
        map = exhibitionService.uploadBaseInfo(expo);
        return this.send(map);
    }

    /**
     * 判断展会名称是否唯一
     * @param expoName
     * @return
     */
    @GetMapping("/expoIsRepeat")
    public Result ExpoRepeat(String expoName){
        try {
            exhibitionService.expoRepeat(expoName);
            return this.send(1,"展会名称唯一");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }

    }

    /**
     * 验证展位信息
     * @param expo
     * @return 返回的字符串为错误信息
     */
    private String validateStandInfo(ExpoDto expo, User user) {
        Exhibition dbExpo = exhibitionService.findExpoById(expo.getExpoId());
        if (!dbExpo.getUserId().equals(user.getId())) {
            return "权限不足";
        }
        int standTotal = 0;
        List<String> hallNames = new ArrayList<>();
        for (HallDto h : expo.getHallDto()) {
            if (hallNames.contains(h.getHallName())) {
                return "同一展会下的展馆名称不能重复";
            } else {
                hallNames.add(h.getHallName());
            }
            List<String> areaNames = new ArrayList<>();
            for (AreaDto a : h.getArea()) {
                if (areaNames.contains(a.getAreaName())) {
                    return "同一展会下的展馆名称不能重复";
                } else {
                    areaNames.add(a.getAreaName());
                }
                for (StandDto s : a.getStand()) {
                    Integer start = s.getStart();
                    Integer end = s.getEnd();
                    if (start > end) {
                        return "展位开始编号不能大于等于结束编号";
                    }
                    standTotal += s.getEnd() - s.getStart() + 1;
                }
            }
        }
        if (standTotal != expo.getStandTotal()) {
            return "设置的展位个数和输入的展会规模不一致";
        }
        return null;
    }

    /**
     * 上传展会展位
     * @param expo
     * @return Result
     */
    @PostMapping("/create/stand")
    public Result uploadSandInfo(@Valid ExpoDto expo, HttpServletRequest request){
        User user = this.getUserFromSession(request);
        String errorMsg = this.validateStandInfo(expo, user);
        if (errorMsg != null) {
            return this.send(1001, errorMsg);
        }
        Map<String, Object> map = exhibitionService.saveOrUpdateStandInfo(expo.getHallDto(),expo.getExpoId());
        return this.send(map);
    }

    // todo
    /**
     *删除展馆信息
     * @param expoId
     * @param hallId
     * @return
     */
    @PostMapping("/delHall")
    public Result delHall(Integer expoId,Integer hallId,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.delHall(expoId,hallId);
            return this.send(1,"删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 上传历史展会
     * @param e
     * @return
     */
    @PostMapping("/create/expoHistory")
    public Result uploadExhibitionHistory(@Valid ExpoHistoryDto e,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.uploadExhibitionHistory(e.getExpoHistory(),e.getExpoId());
        } catch (Exception e1) {
            return this.send(-1,e1.getMessage());
        }
        return this.send(1,"历史展会上传成功");

    }

    /**
     * 上传展会活动
     * @return Result
     */
    @PostMapping("/create/expoActivity")
    public Result uploadExhibitionActivity(@Valid ExpoActivityDto e,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.uploadExhibitionActivity(e.getActivityList(),e.getExpoId());
        } catch (Exception e1) {
            return this.send(-1,e1.getMessage());
        }
        return this.send(1,"展会活动上传成功");
    }

    /**
     * 已发布展览中，根据用户id获得指定状态的展会
     * @return
     */
    @GetMapping("/getExpo")
    public Result getUserExhibitionList(HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        Integer userId = user.getId();
        Map<String,Object> map = exhibitionService.getUserExpoList(userId);
        return this.send(map,1,"返回成功");
    }

    /**
     * 取消展会，
     * @param expoId 展会id
     * @return
     */
    @PostMapping("/cancelExpo")
    public Result cancelExpo(Integer expoId,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-1,"请登录");
        }
        Integer userId = user.getId();
        try {
            exhibitionService.cancelExpo(expoId,userId);
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
        return this.send(1,"操作成功");
    }
    /**
     * 根据展会的名称下载未使用的验证码
     * @param request
     * @param response
     * @param expoId
     * @return
     */
    @GetMapping("/downloadVerify")
    public Result downloadVerify(HttpServletRequest request,
                                 HttpServletResponse response,
                                 Integer expoId){
        try {
            List<String> list = exhibitionService.getVerifyCode(expoId);
            VerifyCodeExportUtil verifyExport = new VerifyCodeExportUtil(request,response,list);
            verifyExport.outputFile();
            return this.send(1,"下载成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 参展商登陆,输入验证码,返回展会名称和展会id
     * @param verifyCode
     * @return
     */
    @PostMapping("/participantLogin")
    public Result participantLogin(String verifyCode,HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-1,"请登录");
        }
        Integer userId =user.getId();
        try {
          ExpoOfUser e = exhibitionService.participantLogin(verifyCode,userId);
          map.put("expo",e);
            return this.send(e,1,"验证通过");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }





    /**
     * 在参展商选择自己展位的时候，查询展位是否已经入驻，如果入驻则提示用户请输入自己的展位或者联系主办方，展位已经被占用,
     *
     * @param standId
     * @return
     */
    @GetMapping("/standRepeat")
    public Result verifyStand(Integer standId){
        try {
            exhibitionService.verifyStand(standId);
            return this.send(1,"展位未被占用");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 上传参展商信息
     * @param c
     * @return
     */
    @PostMapping("/createParticipant")
     public Result createParticipant(@Valid ParticipantDetailDto c,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-1,"请登录");
        }
        Integer userId =user.getId();
        try {
            Integer participantId = exhibitionService.createParticipant(c,userId);
            return this.send(participantId,1,"上传参展商信息成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 根据展会id获取所有展馆名称和id
     * @param expoId
     * @return
     */
    @GetMapping("/hallName")
    public Result getHall(Integer expoId){
        Map<String,Object> map;
        try {
            map= exhibitionService.getHallByExpoId(expoId);
            return this.send(map,1,"返回成功");
        } catch (Exception e) {
            return this.send(-1,"查询失败");
        }
    }


    /**
     * 通过展馆id获取展区名称和id
     * @param hallId
     * @return
     */
    @GetMapping("/areaName")
    public Result getArea(Integer hallId){
        Map<String,Object> map;
        try {
            map = exhibitionService.getAreaByHallId(hallId);
            return this.send(map,1,"返回成功");
        } catch (Exception e) {
            return this.send(-1,"查询失败");
        }
    }
    /**
     * 通过展区id获得展位信息
     * @param areaId
     * @return
     */
    @GetMapping("/stand")
    public Result getStand(Integer areaId){
        Map<String,Object> map;
        try {
            map = exhibitionService.getStand(areaId);
            return this.send(map,1,"返回成功");
        } catch (Exception e) {
            return this.send(-1,"返回失败");
        }
    }


    // todo
    /**
     * 根据展馆id分页获取参展商信息
     * @param hallId
     * @return
     */
    @GetMapping("/getParticipantByHallId")
    public Result getParticipantByHallId(@RequestParam("hallId") Integer hallId,
                                 @RequestParam(value = "page",defaultValue = "1") Integer page,
                                 @RequestParam(value = "limit",defaultValue = "20") Integer limit){
        Integer count = exhibitionService.countParticipantByHallId(hallId);
        if (count!=null){
            try {
                Map<String,Object> map = new HashMap<>();
                List<Participants> list = exhibitionService.getParticipantList(hallId,page,limit);
                map.put("list",list);
                map.put("count",count);
                return this.send(map,1,"返回成功");
            } catch (Exception e) {
                return this.send(-1,e.getMessage());
            }
        }
        return this.send(1,"暂无参展商入驻");
    }

    // todo
    /**
     * 主办方修改参展商展位
     * @return
     */
    @PostMapping("/modifyParticipantStand")
    public Result modifyParticipantStandByManager(@Valid ModifyStandInfoDto m,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.modifyParticipantStandByManager(m);
            return this.send(1,"修改成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 获得展会的历史展会
     * @param expoId
     * @return
     */
    @GetMapping("/getExpoHistory")
    public Result getExpoHistory(Integer expoId){
        try {
            Map<String,Object> map = exhibitionService.getExpoHistory(expoId);
            return this.send(map,1,"返回成功");
        } catch (Exception e) {
            return this.send(-1,"返回失败");
        }
    }

    /**
     *返回展会下的活动
     * @param expoId
     * @return
     */
    @GetMapping("/getExpoActivity")
    public Result getExpoActivity(Integer expoId){
        try {
            Map<String,Object> map = exhibitionService.getExpoActivity(expoId);
            return this.send(map,1,"返回成功");
        } catch (Exception e) {
            return this.send(-1,"返回失败");
        }
    }


    /**
     * 根据展会id获取展会基本信息
     * @param expoId
     * @return
     */
    @GetMapping("/getExpoInfo")
    public Result getExpoBaseInfo(Integer expoId){
        try {
            ExhibitionDto expo =  exhibitionService.getExpoBaseInfo(expoId);
             return this.send(expo,1,"返回成功");
        } catch (Exception e1) {
            return this.send(-1,"获取信息失败");
        }
    }

    /**
     * 修改展会的时候,根据展会id获取展会上传展位时候的展位信息,嵌套格式
     * @param expoId
     * @return
     */
    @GetMapping("/getExpoStand")
    public Result getStandInfo(Integer expoId){
        List<HallDto> list = exhibitionService.getStandInfo(expoId);
        return this.send(list);
    }

    /**
     * 修改展会基本信息
     * @param u
     * @param request
     * @return
     */
    @PostMapping("/modifyExpo")
    public Result modifyExpo(UploadExpoDto u,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        Integer userId = user.getId();
        try {
            exhibitionService.modifyExpo(u,userId);
            return this.send(1,"修改成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }

    }

    /**
     * 主办方取消参展商
     * @param participantId
     * @param request
     * @return
     */
    @PostMapping("/cancelParticipant")
    public Result cancelParticipant(Integer participantId,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.cancelParticipant(participantId);
            return this.send(1,"操作成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 修改展会历史
     * @param e
     * @param request
     * @return
     */
    @PostMapping("/modifyHisExpo")
    public Result modifyHisExpo(@Valid ExpoHistoryDto e,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.modifyHisExpo(e);
            return this.send(1,"修改成功");
        } catch (Exception e1) {
            return this.send(-1,e1.getMessage());
        }
    }

    /**
     *修改展会活动
     * @param e
     * @param request
     * @return
     */
    @PostMapping("/modifyExpoActivity")
    public  Result modifyExpoActivity(@Valid ExpoActivityDto e,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.modifyExpoActivity(e);
            return this.send(1,"修改成功");
        } catch (Exception e1) {
            return this.send(-1,"修改失败");
        }
    }





    /**
     * 获得用户的参展商信息列表
     * @param status 参展商信息状态，no：正在进行，yes:已经结束
     * @return
     */
    @GetMapping("/getParticipantsList")
    public Result getParticipantsList(String status,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)) {
            return this.send(-2,"请登陆");
        }
        try {
            List<ParticipantListDto> participantList = exhibitionService.getParticipantsList(user.getId(),status);
            return this.send(participantList,1,"返回成功");
        } catch (Exception e) {
                return this.send(-1,e.getMessage());
        }
    }

    /**
     * 参展商信息修改界面，获取参展商详情
     * @return
     */
    @GetMapping("/getParticipantsDetail")
    public Result getParticipantsDetail(Integer participantId){
        try {
            ParticipantDetailDto participant = exhibitionService.getParticipantDetail(participantId);
            return this.send(participant,1,"返回成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 修改参展商信息
     * @param participantDetailDto
     * @return
     */
    @PostMapping("/modifyParticipant")
    public Result modifyParticipant(ParticipantDetailDto participantDetailDto,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)) {
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.modifyParticipant(participantDetailDto);
            return this.send(1,"修改成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }
    /**
     * 上传参展文件
     * @param participantId 参展商id
     * @param key
     * @param fileType 文件类型
     * @return
     */
    @PostMapping("/participantFile")
    public Result uploadParticipantFile(Integer participantId,String key ,String fileName,String fileType,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)){
            return this.send(-2,"请登陆");
        }
        Integer userId = user.getId();
        try {
            exhibitionService.uploadParticipantFile(participantId,key,fileName,fileType,userId);
            return this.send(1,"上传成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }

    /**
     * 获得参展商文件
     * @param participantId
     * @return
     */
    @GetMapping("/getParticipantFile")
    public Result getParticipantFile(Integer participantId){
        try {
           List<FileManage> file =  exhibitionService.getParticipantFile(participantId);
            return this.send(file,1,"返回成功");
        } catch (Exception e) {
            e.printStackTrace();
            return this.send(-1,e.getMessage());
        }
    }
    /**
     * 删除参展商文件
     * @param fileId
     * @return
     */
    @PostMapping("/delParticipantFile")
    public Result delParticipantFile(Integer fileId,HttpServletRequest request){
        User user = this.getUserFromSession(request);
        if (Objects.isNull(user)) {
            return this.send(-2,"请登陆");
        }
        try {
            exhibitionService.delParticipantFile(fileId,user.getId());
            return this.send(1,"删除成功");
        } catch (Exception e) {
            return this.send(-1,e.getMessage());
        }
    }










}
